package com.jc.service.api.appgame;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import com.alibaba.fastjson.JSONObject;
import com.jc.common.util.Base64Util;
import com.jc.common.util.CommonStr;
import com.jc.ds.base.service.BaseServiceException;
import com.jc.ds.model.UserOrder;
import com.jc.framework.enums.AppServerApi;
import com.jc.framework.enums.Conclusion;
import com.jc.framework.enums.LogType;
import com.jc.framework.enums.OrderType;
import com.jc.framework.util.PropertyPlaceholder;
import com.jc.framework.util.SpringUtils;
import com.jc.framework.web.ResponseBaseModel;
import com.jc.framework.web.ResponseResultModel;
import com.jc.model.AppRespModel;
import com.jc.service.api.BaseDual;
import com.jc.service.api.appgame.model.Param;
import com.jc.service.api.appgame.model.RechargeParam;
import com.jc.service.apilog.ApiLogService;
import com.jc.service.appinterface.AppInterfaceService;
import com.jc.service.chain.ChainResult;
import com.jc.service.userorder.UserOrderService;

/***
 * 
 * @author Administrator
 * 
 */
public class recharge extends BaseDual<Param> {

	// 对称加密密钥
	final String userEncrypt = (String) PropertyPlaceholder.getProperty("user.encrypt");
	// 充值交易币种(VRT)
	final String currencyName = (String) PropertyPlaceholder.getProperty("transfer.currency.name");
	// 单次最小充值金额
	final String changeMinAmount = (String) PropertyPlaceholder.getProperty("change.min.amount");
	// 单次最小提现金额
	final String withdrawMinAmount = (String) PropertyPlaceholder.getProperty("withdraw.min.amount");
	// 公司账号用户ID
	final String companyUserId = (String) PropertyPlaceholder.getProperty("company.user.id");
	
	final String txOpen = (String) PropertyPlaceholder.getProperty("game.tx.open");
	
	private UserOrderService userOrderService = SpringUtils.getBean(UserOrderService.class);
	
	private ApiLogService apiLogService = SpringUtils.getBean(ApiLogService.class);
	
	
    private AppInterfaceService appInterfaceService = SpringUtils.getBean(AppInterfaceService.class);

	public ResponseEntity<?> dual(JSONObject data) {
		ChainResult transfer; // 区块链交易结果
		Param param = null;
		RechargeParam rechargeParam = null;
		
		try {
			param = getData(data);
			
			if(param == null || StringUtils.isBlank(param.getEncrypt())) {
				throw new BaseServiceException("缺少必填参数: encrypt ");
			}
			
			rechargeParam = JSONObject.parseObject(Base64Util.decode(param.getEncrypt()), RechargeParam.class);
			
			if (StringUtils.isBlank(rechargeParam.getPayPass())) {
				throw new BaseServiceException("缺少必填参数: 支付密码不能为空");
			}
			if (rechargeParam.getAmount() == 0) {
				throw new BaseServiceException("缺少必填参数: 充值金额不能为0");
			}

			if (rechargeParam.getUserId() == null || rechargeParam.getUserId() < 1) {
				throw new BaseServiceException("缺少必填参数: 缺少用户ID");
			}

			if (rechargeParam.getBusinessType() < 0) {
				throw new BaseServiceException("缺少必填参数: 缺少业务类型");
			}
			
			if (StringUtils.isBlank(rechargeParam.getPayPass())) {
				throw new BaseServiceException("缺少必填参数: 缺少支付密码");
			}
			
			if (rechargeParam.getBusinessType() < 0) {
				throw new BaseServiceException("缺少必填参数: ");
			}
			
			if(StringUtils.isBlank(rechargeParam.getChannel())) {
				throw new BaseServiceException("缺少必填参数: channel");
			}
			
			
			
			
			
			
			getLoger().info("APP 游戏调用充值/提现接口 -----> 参数 : {} " , JSONObject.toJSONString(rechargeParam));
			
			
			UserOrder _udorder = new UserOrder();
			_udorder.setChannelOrderId(rechargeParam.getOrderId());
			List<UserOrder> _extisList = userOrderService.queryAll(_udorder);
			
			if(!CollectionUtils.isEmpty(_extisList)) {
				throw new BaseServiceException("该订单号已经存在,请重新发起交易");
			}		
			
			if (rechargeParam.getBusinessType() == OrderType.VRT充值.getIndex()) {
				//校验接口
				Map<String,Object> map = new HashMap<String, Object>();
				map.put("password", rechargeParam.getPayPass());
				map.put("id", rechargeParam.getUserId());
				
				AppRespModel appRespModel = appInterfaceService.AppInterfaceHttp(AppServerApi.CHECK_PAY_PASSWORD.getName(), map , LogType.APP_CHECK_PAYPASSWORD);
				
	            if ("1".equals(appRespModel.getReturnCode())){
	            	getLoger().info("校验支付密码结果 ----->  : {} " , JSONObject.toJSONString(appRespModel) );
	            	throw new BaseServiceException("交易失败， 支付密码错误! ");
	            }
				
				transfer = userOrderService.transfer(currencyName, BigDecimal.valueOf(rechargeParam.getAmount()),
						rechargeParam.getUserId(), Long.valueOf(companyUserId), "无备注", rechargeParam.getBusinessType(),
						rechargeParam.getChannel(),rechargeParam.getOrderId());

				if (transfer == null) {
					apiLogService.addApiLog(LogType.APP_GAME_REQUEST_RECHARGE, JSONObject.toJSONString(rechargeParam), Conclusion.FAIL, "充值调用链上出错, 链上返回信息为空", null);
					ResponseBaseModel errorModel = new ResponseBaseModel();
					errorModel.setCode(9999);
					errorModel.setMessage("提现调用链上出错, 链上返回信息为空!");
					return new ResponseEntity<>(errorModel , HttpStatus.OK);
				}

				if (CommonStr.SUCCESS.equals(transfer.getReturn_code())) {
					apiLogService.addApiLog(LogType.APP_GAME_REQUEST_RECHARGE, JSONObject.toJSONString(rechargeParam), Conclusion.OK, "", JSONObject.toJSONString(transfer));
					// 充值请求成功
					return new ResponseEntity<>(new ResponseResultModel<String>(null), HttpStatus.OK);
				} else {
					apiLogService.addApiLog(LogType.APP_GAME_REQUEST_RECHARGE, JSONObject.toJSONString(rechargeParam), Conclusion.FAIL, "", JSONObject.toJSONString(transfer));
					ResponseBaseModel errorModel = new ResponseBaseModel();
					errorModel.setCode(9999);
					errorModel.setMessage(transfer.getReturn_msg());
					return new ResponseEntity<>(errorModel , HttpStatus.OK);
				}
			} else {
				
				if(StringUtils.isBlank(txOpen) || StringUtils.equals(txOpen, "0")) {
					ResponseBaseModel errorModel = new ResponseBaseModel();
					errorModel.setCode(9999);
					errorModel.setMessage("系统暂停提现谢谢 请联系公司!");
					return new ResponseEntity<>(errorModel, HttpStatus.OK);
				}
				// 先调用游戏接口扣减游戏币, 然后再进行区块链转账请求，如果后面该条请求处理失败，则调用添加金币为用户增加金币,防止用户在请求提现后继续游戏输分，
				// 导致提现交易成功后金币不够扣
				transfer = userOrderService.transfer(currencyName, BigDecimal.valueOf(rechargeParam.getAmount()),
						Long.valueOf(companyUserId), rechargeParam.getUserId(), "无备注", rechargeParam.getBusinessType(),
						rechargeParam.getChannel(),rechargeParam.getOrderId());
				
				if (transfer == null) {
					apiLogService.addApiLog(LogType.APP_GAME_REQUEST_WITHDRAW, JSONObject.toJSONString(rechargeParam), Conclusion.FAIL, "提现调用链上出错, 链上返回信息为空", null);
					ResponseBaseModel errorModel = new ResponseBaseModel();
					errorModel.setCode(9999);
					errorModel.setMessage("提现调用链上出错, 链上返回信息为空!");
					return new ResponseEntity<>(errorModel, HttpStatus.OK);
				}
				
				if (CommonStr.SUCCESS.equals(transfer.getReturn_code())) {
					// 提现请求成功
					apiLogService.addApiLog(LogType.APP_GAME_REQUEST_WITHDRAW, JSONObject.toJSONString(rechargeParam), Conclusion.OK, "", JSONObject.toJSONString(transfer));
					return new ResponseEntity<>(new ResponseResultModel<String>(null), HttpStatus.OK);
				} else {
					apiLogService.addApiLog(LogType.APP_GAME_REQUEST_WITHDRAW, JSONObject.toJSONString(rechargeParam), Conclusion.FAIL, "", JSONObject.toJSONString( transfer ));
					ResponseBaseModel errorModel = new ResponseBaseModel();
					errorModel.setCode(9999);
					errorModel.setMessage(transfer.getReturn_msg());
					return new ResponseEntity<>(errorModel , HttpStatus.OK);
				}
			}
		} catch (Exception e) {
			if(e != null && StringUtils.isNotBlank(e.getMessage())) {
				String error = e.getMessage();
				if(e.getMessage().length() > 150) {
					error = StringUtils.substring(e.getMessage(), 0, 150);
				}
				apiLogService.addApiLog(LogType.APP_GAME_REQUEST_WITHDRAW, JSONObject.toJSONString(rechargeParam), Conclusion.FAIL, "程序执行异常 : " + error , null);
			}
			getLoger().error("请求交易出错, {} " , e);
			throw new BaseServiceException(e.getMessage());
		}

	}
}
